#region File header
// Project: SharpWars.Core, File: GameRoomForm.cs
// Namespace: SharpWars.Core.Forms, Class: GameRoomForm
// Path: F:\Coder\Projekty\Windows\Gry\SharpWars\SharpWars.Core\Forms, Author: Sebastian Haba (sho@gisz.net.pl)
// Code lines: 268, Size of file: 7,05 KB
// Creation date: 2007-02-23 19:53
// Last modified: 2007-02-24 14:42
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SharpWars.Core.Network;
using System.Runtime.InteropServices;

namespace SharpWars.Core.Forms
{
	public partial class GameRoomForm : Form
	{
		private Client client = null;

		private List<Player> players = new List<Player>();

		public GameRoomForm()
		{
			InitializeComponent();
		}
		
		private delegate void PlayerEventDelegate( object sender, PlayerEventArgs e );
		
		private void AddPlayerToList( Player player )
		{
			this.players.Add( player );

			ListViewItem name = new ListViewItem( player.Name );
			name.SubItems.Add( new ListViewItem.ListViewSubItem( name, player.Ready.ToString() ) );
			this.playersListView.Items.Add( name );
		}
		
		public GameRoomForm( Client client ) : this()
		{
			this.client = client;
			this.client.PlayerJoin         += new PlayerEventHandler( OnPlayerJoin );
			this.client.PlayerKicked       += new PlayerEventHandler( OnPlayerKicked );
			this.client.PlayerListReceived += new PlayerEventHandler( OnPlayerListReceived );
			this.client.MessageReceived    += new MessageEventHandler( OnMessageReceived );
			this.client.PlayerReady        += new PlayerEventHandler( OnPlayerReady );
			this.client.PlayerDisconnected += new PlayerEventHandler( OnPlayerDisconnected );
		
			GameMap.instance.Client = client;
		
			Player player = new Player();
			player.Name   = this.client.Name;
			player.Ready  = false;
			AddPlayerToList( player );
			
			WriteSystemMessageToChat( "Welcome In Sharp Wars Game Room" );
		}

		private void OnPlayerReady( object sender, PlayerEventArgs e )
		{
			if( InvokeRequired )
			{
				PlayerEventDelegate playerEvent = new PlayerEventDelegate( OnPlayerReady );
				Invoke( playerEvent, new object[]{ sender, e } );
			}
			else
			{
				ChangeReadyStatus( e.Name, "True" );
			}	
		}
		
		private void ChangeReadyStatus( string name, string status )
		{
			foreach( ListViewItem item in this.playersListView.Items )
			{
				if( item.Text == name )
				{
					item.SubItems[1].Text = status;
				}
			}
		}

		private delegate void MessageEventDelegate( object sender, MessageEventArgs e );

		private void OnMessageReceived( object sender, MessageEventArgs e )
		{
			if( InvokeRequired )
			{
				MessageEventDelegate messageEvent = new MessageEventDelegate( OnMessageReceived );
				Invoke( messageEvent, new object[]{ sender, e } );
			}
			else
			{
				WriteMessageToChat( e.Sender, e.Message );
			}
		}
		
		private void WriteSystemMessageToChat( string message )
		{
			if( this.chatList.Text.Length > 0 )
			{
				this.chatList.AppendText( "\n" );
			}
			
			this.chatList.AppendText( "[" + DateTime.Now.ToLongTimeString() + "] *** " + message + " ***" );
			ScrollChat();

			GameMap.instance.AddFadeText
			(
				"*** " + message + " ***",
				Color.White
			);
		}
		
		private void WriteMessageToChat( int sender, string message )
		{
			if( this.chatList.Text.Length > 0 )
			{
				this.chatList.AppendText( "\n" );
			}

		
			this.chatList.AppendText( "[" + DateTime.Now.ToLongTimeString() + "] " + this.client.Players[sender].Name + ": " + message );
			ScrollChat();

			GameMap.instance.AddFadeText
			(
				this.client.Players[ sender ].Name + ": " + message,
				Color.White
			);
		}
		
		private void WriteSelfMessageToChat( string message )
		{
			if( this.chatList.Text.Length > 0 )
			{
				this.chatList.AppendText( "\n" );
			}
			
			this.chatList.AppendText( "[" + DateTime.Now.ToLongTimeString() + "] " + this.client.Name + ": " + message );
			ScrollChat();

			GameMap.instance.AddFadeText
			(
				this.client.Name + ": " + message,
				Color.White
			);
		}

		private void ScrollChat()
		{
			this.chatList.Select( this.chatList.TextLength - 2, this.chatList.TextLength - 1 );
			this.chatList.ScrollToCaret();
		}

		private Player CreatePlayer( PlayerEventArgs e )
		{
			Player client   = new Player();
			client.PlayerID = e.PlayerID;
			client.Name     = e.Name;
			client.Ready    = e.Ready;
			
			return client;
		}

		private delegate void SimpleDelegate();

		private void OnPlayerListReceived( object sender, PlayerEventArgs e )
		{
			if( InvokeRequired )
			{
				PlayerEventDelegate playerEvent = new PlayerEventDelegate( OnPlayerListReceived );
				Invoke( playerEvent, new object[]{ sender, e } );
			}
			else
			{
				AddPlayerToList( CreatePlayer( e ) );
			}	
		}
		
		private void RemovePlayerFromList( Player player )
		{
			this.players.Remove( player );

			foreach( ListViewItem item in this.playersListView.Items )
			{
				if( item.Text == player.Name )
				{
					this.playersListView.Items.Remove( item );
					break;
				}
			}
		}

		private void OnPlayerKicked( object sender, PlayerEventArgs e )
		{
			if( InvokeRequired )
			{
				PlayerEventDelegate playerEvent = new PlayerEventDelegate( OnPlayerKicked );
				Invoke( playerEvent, new object[]{ sender, e } );
			}
			else
			{
				WriteSystemMessageToChat( e.Name + " has been kicked." );
				RemovePlayerFromList( CreatePlayer( e ) );
			}
		}
		
		private void OnPlayerDisconnected( object sender, PlayerEventArgs e )
		{
			if( InvokeRequired )
			{
				PlayerEventDelegate playerEvent = new PlayerEventDelegate( OnPlayerDisconnected );
				Invoke( playerEvent, new object[]{ sender, e } );
			}
			else
			{
				WriteSystemMessageToChat( e.Name + " disconnected." );
				RemovePlayerFromList( CreatePlayer( e ) );
			}
		}

		private void OnPlayerJoin( object sender, PlayerEventArgs e )
		{
			if( InvokeRequired )
			{
				PlayerEventDelegate playerEvent = new PlayerEventDelegate( OnPlayerJoin );
				Invoke( playerEvent, new object[]{ sender, e } );
			}
			else
			{
				WriteSystemMessageToChat( e.Name + " joined to game room" );
				AddPlayerToList( CreatePlayer( e ) );
			}
		}

		private void OnChatTextBoxKeyDown( object sender, KeyEventArgs e )
		{
			if( e.KeyCode == Keys.Enter )
			{
				if( this.chatTextBox.Text.Length > 0 && this.chatTextBox.Text.Length < 256 )
				{
					this.client.SendMessageToAll( this.chatTextBox.Text );
					WriteSelfMessageToChat( this.chatTextBox.Text );
					this.chatTextBox.Clear();
					this.chatTextBox.Focus();
				}
			}
		}

		private void OnReadyButtonClick( object sender, EventArgs e )
		{
			this.readyButton.Enabled = false;
			this.client.Ready();
			
			ChangeReadyStatus( this.client.Name, "True" );
		}

		private void OnLoadButtonClick( object sender, EventArgs e )
		{
			using( LoadGameForm form = new LoadGameForm( this.client, this ) )
			{
				form.ShowDialog( this );
			} // using (form)
		}

		/// <summary>
		/// Connected players
		/// </summary>
		/// <returns>List</returns>
		public List<Player> ConnectedPlayers
		{
			get
			{
				return this.players;
			} // get
		} // ConnectedPlayers
	}
}